package com.bosssoft.trainee.nontax.controller;

import com.bosssoft.trainee.nontax.config.redis.RedisService;
import com.bosssoft.trainee.nontax.entity.po.PermissionPO;
import com.bosssoft.trainee.nontax.entity.po.UserPO;
import com.bosssoft.trainee.nontax.entity.UserInfo;
import com.bosssoft.trainee.nontax.utils.JwtUtils;
import com.bosssoft.trainee.nontax.utils.MenuTree;
import com.bosssoft.trainee.nontax.utils.Result;
import com.bosssoft.trainee.nontax.entity.vo.RouterVO;
import com.bosssoft.trainee.nontax.entity.vo.TokenVO;
import io.jsonwebtoken.Jwts;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/sysUser")
public class SysUserController {

    @Resource
    private RedisService redisService;

    @Resource
    private JwtUtils jwtUtils;

    private static final String TOKEN="token";

    private static final String TOKEN_NOTHING="token_";
    /**
     * 刷新token
     * @param request
     * @return
     */
    @PostMapping("/refreshToken")
    public Result<TokenVO> refreshToken(HttpServletRequest request){

        //从header中获取前端提交的token
        String token = request.getHeader(TOKEN);
        //如果header中没有token，则从参数中获取
        if (ObjectUtils.isEmpty(token)){
            token = request.getParameter(TOKEN);
        }
        //从Spring Security上下文获取用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        //获取身份信息
        UserDetails details = (UserDetails) authentication.getPrincipal();
        //重新生成token
        String reToken = "";
        //验证原来的token是否合法
        if (Boolean.TRUE.equals(jwtUtils.validateToken(token, details))){
            //生成新的token
            reToken = jwtUtils.refreshToken(token);
        }
        //获取本次token的到期时间，交给前端做判断
        long expireTime = Jwts.parser().setSigningKey(jwtUtils.getSecret())
                .parseClaimsJws(reToken.replace("jwt_",""))
                .getBody().getExpiration().getTime();
        //清除原来的token信息
        String oldTokenKey = TOKEN_NOTHING + token;
        redisService.del(oldTokenKey);
        //存储新的token
        String newTokenKey = TOKEN_NOTHING + reToken;
        redisService.set(newTokenKey, reToken, jwtUtils.getExpiration() / 1000);
        //创建TokenVo对象
        TokenVO tokenVo = new TokenVO(expireTime, reToken);
        //返回数据
        return Result.ok(tokenVo).message("token刷新成功");
    }


    /**
     * 查询用户登录信息
     * @return
     */
    @GetMapping(value ="/getInfo")
    public Result<? extends Object> getInfo() {
        //从Spring Security上下文获取用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        //判断authentication对象是否为空
        if (authentication == null) {
            return Result.error().message("用户信息查询失败");
        }
        //获取用户信息
        UserPO userPO = (UserPO) authentication.getPrincipal();
        //用户权限集合
        List<PermissionPO> permissionPOList = userPO.getPermissionPOList();
        //获取角色权限编码字段
        Object[] roles = permissionPOList.stream()
                .filter(Objects::nonNull)
                .map(PermissionPO::getCode).toArray();
        //创建用户信息对象
        UserInfo userInfo = new UserInfo(userPO.getId(), userPO.getNickName(), userPO.getAvatar(), null, roles);
        //返回数据
        return Result.ok(userInfo).message("用户信息查询成功");
    }


    /**
     * 获取菜单数据
     * @return
     */
    @GetMapping("/getMenuList")
    public Result<List<RouterVO>> getMenuList(){
        //从Spring Security上下文获取用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        //获取用户信息
        UserPO userPO = (UserPO) authentication.getPrincipal();
        //获取相应的权限
        List<PermissionPO> permissionPOList = userPO.getPermissionPOList();
        //筛选目录和菜单
        List<PermissionPO> collect = permissionPOList.stream()
                .filter(item -> item != null && item.getType() !=2)
                .collect(Collectors.toList());
        //生成路由数据
        List<RouterVO> routerVOList = MenuTree.makeRouter(collect, 0L);
        //返回数据
        return Result.ok(routerVOList).message("菜单数据获取成功");
    }

    /**
     * 退出登录
     * @param request
     * @param response
     * @return
     */
    @PostMapping("/logout")
    public Result<Object> logout(HttpServletRequest request, HttpServletResponse response){
        String token = request.getHeader(TOKEN);
        if (ObjectUtils.isEmpty(token)){
            token = request.getParameter(TOKEN);
        }
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null) {
            new SecurityContextLogoutHandler().logout(request, response, authentication);
            String key = TOKEN_NOTHING + token;
            redisService.del(key);
        }
        return Result.ok().message("用户退出成功");
    }

}
